home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
utils
/
gemfxm15.lzh
/
WINDXMPL.LZH
/
WINDXMPL.C
next >
Wrap
C/C++ Source or Header
|
1990-05-27
|
12KB
|
427 lines
/* tab expansion/compression should be set to 4 in your editor */
/**************************************************************************
*
* WINDXMPL.C - Demo of handling an object tree in a window, with minimal
* emulation of form_do processing. (And with a special demo
* of editing a text field based on either a mouse click or
* a menu selection; a strange feature someone asked for.)
*
* This file demos many of the alternate AES bindings
* routines such as frmx_center and evnx_multi.
*************************************************************************/
#include <osbind.h>
#include <gemfast.h>
#include "windxmpl.h"
#define WI_KIND (SIZER+MOVER+CLOSER+NAME)
#define NO_WINDOW -1
#define TRUE 1
#define FALSE 0
OBJECT *menutree;
OBJECT *windtree;
int wchar;
int hchar;
int wi_handle = NO_WINDOW;
char wi_name[] = " Window Demo ";
extern int gl_apid;
/**************************************************************************
*
* prg_init - Standard GEM startup.
*
*************************************************************************/
prg_init()
{
int dmy;
appl_init();
if (!rsrc_load("WINDXMPL.RSC")) {
form_alert(1,"[1][ | Can't load RSC! | ][ Fatal ]");
appl_exit();
Pterm(1);
}
graf_handle(&wchar, &hchar, &dmy, &dmy); /* For window min sizes */
rsrc_gaddr(R_TREE, MENUTREE, &menutree);
rsrc_gaddr(R_TREE, WINDTREE, &windtree);
menu_bar(menutree, TRUE);
graf_mouse(ARROW, 0L);
}
/**************************************************************************
*
* prg_exit - Standard GEM exit.
*
*************************************************************************/
prg_exit()
{
w_close();
menu_bar(menutree, FALSE);
rsrc_free();
appl_exit();
Pterm(0);
}
/**************************************************************************
*
* w_open - Create and open a window.
* The display tree is centered, then the window is sized to hold it.
*
*************************************************************************/
w_open()
{
GRECT wrect;
GRECT treerect;
if (wi_handle != NO_WINDOW) { /* if window is already open, */
return wi_handle; /* just return the handle. */
}
frmx_center(windtree, &treerect); /* center tree, sizes in treerect */
winx_calc(WC_BORDER, WI_KIND, treerect, &wrect); /* calc window fullsize */
wi_handle = wind_create(WI_KIND, wrect); /* create window */
if (wi_handle < 0) {
form_error(4); /* can't open another window */
wi_handle = NO_WINDOW;
} else {
wind_set(wi_handle, WF_NAME, wi_name, 0L); /* set window title */
wind_open(wi_handle, wrect); /* open window */
}
return wi_handle;
}
/**************************************************************************
*
* w_close - Close and delete a window.
*
*************************************************************************/
w_close()
{
if (wi_handle != NO_WINDOW) { /* only do close processing */
wind_close(wi_handle); /* if the window is open! */
wind_delete(wi_handle);
wi_handle = NO_WINDOW;
}
}
/**************************************************************************
*
* do_redraw - Standard AES redraw handler for trees in windows.
*
*************************************************************************/
do_redraw(window, ptree, predrawrect)
register int window;
register OBJECT *ptree;
register GRECT *predrawrect;
{
register int calltype;
register int doneflag;
GRECT t1;
GRECT t2;
/*
* process the rectangle list for the window. for each intersection of
* the area to be redrawn with a visible window rectangle, call objc_draw
* to draw that portion of the menu.
*/
wind_update(BEG_UPDATE);
calltype = WF_FIRSTXYWH;
doneflag = FALSE;
do {
winx_get(window, calltype, &t1);
if (t1.g_w && t1.g_h) {
if (rc_intersect(predrawrect, &t1) && t1.g_w && t1.g_h) {
objc_draw(ptree, R_TREE, MAX_DEPTH, t1);
}
} else {
doneflag = TRUE;
}
calltype = WF_NEXTXYWH;
} while (doneflag == FALSE);
wind_update(END_UPDATE);
}
/**************************************************************************
*
* send_edmsg - Send a message to ourselves to edit the window field.
* The message looks exactly like a normal MN_SELECTED.
* This allows us to re-schedule the edit function after topping our
* window, in case the user picks the EDIT menu item while an ACC
* window is topped.
*
*************************************************************************/
send_edmsg()
{
static int edmsg[8] = {MN_SELECTED, 0, 0, MENUFILE, MENUEDFN};
edmsg[1] = gl_apid;
appl_write(gl_apid, 16, edmsg);
}
/**************************************************************************
*
* hndl_message - Standard message handling code.
*
*************************************************************************/
hndl_message(msgbuf)
register int *msgbuf;
{
int dmy;
int top_window;
register OBJECT *ptree = windtree;
GRECT t1, t2;
switch (msgbuf[0]) {
case MN_SELECTED:
switch (msgbuf[4]) {
case MENUQUIT:
prg_exit();
break;
case MENUEDFN:
/*-------------------------------------------------------------------------
* Handling the EDIT FILENAME menu item...
*
* For a request to edit the field in the window, we must first ensure
* that our window is topped (an ACC could be topped). If not, we do
* a wind_set() call to top it, because allowing editing in a background
* window goes against all GEM concepts. After forcing the window to the
* top, we send an edit request back to ourselves, because our window
* doesn't really become topped until we receive back the corresponding
* redraw messages.
*
* We call menu_tnormal() to visually highlight the FILE title; if we're
* here because of a message we sent ourselves, the title won't already
* be highlighted. If we're here because of a genuine menu selection
* by the user, it doesn't hurt to do the call anyway.
*
* If our window is topped, we call form_do() to handle the editing. A
* nasty side effect of form_do() is that it will visually SELECT the
* edit field when the user hits return, so we immediately de-select it.
*
* Before starting the edit dialog, we set the ob_flags value for the
* filename edit field to EDITABLE, EXIT, and DEFAULT. This allows the
* user to type in text and hit <CR> (a natural action), and the <CR>
* causes an exit from form_do() processing because of the DEFAULT flag
* on the edit field. (What, you thought only buttons could be DEFAULT?)
* When the edit is done, we reset the ob_flags for the edit field.
*-----------------------------------------------------------------------*/
menu_tnormal(menutree, MENUFILE, FALSE);
wind_get(0, WF_TOP, &top_window, &dmy, &dmy, &dmy);
if (wi_handle != top_window) {
wind_set(wi_handle, WF_TOP, 0L, 0L);
send_edmsg();
} else {
wind_update(BEG_UPDATE);
ptree[WINDTEFN].ob_flags |= (EDITABLE|EXIT|DEFAULT);
form_do(ptree, WINDTEFN);
winx_get(wi_handle, WF_WORKXYWH, &t1);
objc_change(ptree, WINDTEFN, 0, t1, NORMAL, TRUE);
ptree[WINDTEFN].ob_flags &= ~(EDITABLE|EXIT|DEFAULT);
wind_update(END_UPDATE);
}
break;
}
menu_tnormal(menutree, msgbuf[3], TRUE);
break;
case WM_CLOSED:
prg_exit();
break;
case WM_TOPPED:
case WM_NEWTOP:
wind_set(msgbuf[3], WF_TOP, 0L, 0L);
break;
case WM_REDRAW:
do_redraw(msgbuf[3], ptree, &msgbuf[4]);
break;
case WM_MOVED:
case WM_SIZED:
/*-------------------------------------------------------------------------
* Handling SIZED and MOVED window requests...
*
* AES has given us the window outside dimensions of the user's mouse
* activity with the window controls, convert to workarea dimensions.
*
* Reposition the object tree at the proper x/y to match the window.
* Use rc_intersect() to ensure that a re-size operation does not exceed
*